package cn.congzhou.crm.web.realm;

import cn.congzhou.crm.domain.Employee;
import cn.congzhou.crm.mapper.EmployeeMapper;
import cn.congzhou.crm.mapper.RoleMapper;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;


@Component("crmRealm")
public class CRMRealm extends AuthorizingRealm{

    @Autowired
    private EmployeeMapper employeeMapper;

    @Autowired
    private RoleMapper roleMapper;

    //将容器中的配置的凭证匹配器注入给当前的Realm对象
    //在该Realm中使用指定的凭证匹配器来完成密码匹配的操作
    @Autowired
    @Override
    public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
        super.setCredentialsMatcher(credentialsMatcher);
    }


    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        String username = token.getPrincipal().toString();
        Employee emp = employeeMapper.selectEmployeeByUsername(username);
        if(emp == null){
            return null;//表示系统中没有该用户的信息，无法创建realm数据源，会抛账号不存在异常
        }

        return new SimpleAuthenticationInfo(emp,emp.getPassword(),// 把密码告诉了shiro
                ByteSource.Util.bytes(emp.getName()),this.getName());
    }



    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
//      创建授权信息对象返回给安全管理器
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//      获取当前登录的用户，已在认证的方法中查询到当前登录的用户信息，直接使用即可，没有认证成功不会跑到这一步
        Employee emp = (Employee)principals.getPrimaryPrincipal();
//      判断是否为超管
        if(emp.isAdmin()){
//          授予管理员角色
            info.addRole("admin");
//          授予所有权限
            info.addStringPermission("*:*");
        }else{
//          查询当前登录对象的角色编码
            List<String> roles = roleMapper.selectRoleByEmpId(emp.getId());
//          查询当前员工所拥有的权限
            List<String> expressions = roleMapper.selectExpressionsByEmpId(emp.getId());
//          添加角色编码到数据源对象
            info.addRoles(roles);
//          添加权限表达式到数据源对象
            info.addStringPermissions(expressions);
        }

//        将权限信息返回给安全管理器
        return info;
    }


}
